#include <fstream>
#include <iomanip>
#include <unordered_set>

#include "Network/ModsManager.h"
#include "Utils/Utils.h"
#include "Log.h"


namespace PocketSurvival
{
    ModsManager::ModsManager() {}
    ModsManager::~ModsManager() {}

    bool ModsManager::verifyMods(const std::vector<ModInfo> &modInfos)
    {
        if(m_mustVerigyMod == false)
        {
            for (const auto &item : modInfos)
            {
                Log::Info(fmt::format("检测到模组信息: md5:{} name:{} packageName:{} version:{}", item.md5Value, item.name, item.packageName, item.verison));
            }
            return true;
        }

        std::unordered_set<std::string> mustBeInstalledModSet;

        for (const auto &item : modInfos)
        {
            Log::Info(fmt::format("检测到模组信息: md5:{} name:{} packageName:{} version:{}", item.md5Value, item.name, item.packageName, item.verison));
            auto it = m_mustBeInstalledModMap.find(item.packageName);
            if(it != m_mustBeInstalledModMap.end())
            {
                if(it->second.name == item.name && it->second.packageName == item.packageName && it->second.verison == item.verison)
                {
                    for(const std::string &md5Value : it->second.md5Values)
                    {
                        if(md5Value == item.md5Value)
                        {
                            mustBeInstalledModSet.insert(it->second.name);
                            goto verify_next;
                        }
                    }
                }
                Log::Info("必装模组验证不通过");
                return false;

                verify_next:
                continue;
            }

            auto allowIt = m_allowedToUseModMap.find(item.packageName);
            if(allowIt != m_mustBeInstalledModMap.end())
            {
                if(allowIt->second.name == item.name && allowIt->second.packageName == item.packageName && allowIt->second.verison == item.verison)
                {
                    for(const std::string &md5Value : allowIt->second.md5Values)
                    {
                        if(md5Value == item.md5Value)
                        {
                            goto verify_ok;
                        }
                    }
                }
                Log::Info("安装了多余的模组");
                return false;
            }
        verify_ok:;
        }

        if(mustBeInstalledModSet.size() != m_mustBeInstalledModMap.size())
        {
            Log::Info("缺少必须安装的模组");
            return false;
        }
        return true;
    }


    void ModsManager::load()
    {
        std::ifstream inputFile("mods.json");
        if (inputFile)
        {
            try
            {
                nlohmann::json jsonData;
                inputFile >> jsonData;

                Utils::GetJsonValue<bool>(jsonData, m_mustVerigyMod, "VerifyMod", false);
                Utils::GetJsonValue<std::map<std::string, ModsInfo>>(jsonData, m_mustBeInstalledModMap, "MustBeInstalled", {});
                Utils::GetJsonValue<std::map<std::string, ModsInfo>>(jsonData, m_allowedToUseModMap, "AllowedToUse", {});
                inputFile.close();
                return;
            }
            catch (const std::exception &e)
            {
                Log::Error(fmt::format("读取mod配置文件发生错误 : {}", e.what()));
            }
        }
        inputFile.close();
        m_mustVerigyMod = false;
        m_mustBeInstalledModMap["survivalcraft"] = ModsInfo{ { 
            "3f739a80da037d2d2ee168ef27b5d691", 
            "7f1c86a6f2a134d0fc27c9fc922abe37", 
            "4340d35294f61e698213df0d33df3cf0",
            "dcba12d2afaac97d2241471e9f696889"
            }, "SCPAK Resources", "survivalcraft", "1.0.0"};
        m_mustBeInstalledModMap["com.fastdebug"] = ModsInfo{ { "" }, "FastDebug", "com.fastdebug", "1.0.0"};

        nlohmann::json jsonData;
        jsonData["VerifyMod"] = m_mustVerigyMod;
        jsonData["MustBeInstalled"] = m_mustBeInstalledModMap;
        jsonData["AllowedToUse"] = m_allowedToUseModMap;
        std::ofstream outStream("mods.json");
        if(outStream)
        {
            outStream << std::setw(4) << jsonData;
        }
        else
        {
            Log::Error("配置文件保存失败");
        }
        outStream.close();
    }
    
    void ModsManager::save() {}

} // namespace PocketSurvival
